#!/bin/bash -e
#
#   Neutron3529's Unity Game Plugin
#   Copyright (C) 2022 Neutron3529
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU Affero General Public License as
#   published by the Free Software Foundation, either version 3 of the
#   License, or (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU Affero General Public License for more details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
############################################################################
#
#   * compile instructions: put this file and `utils.cs` in `steamapps`
#   * folder, open a terminal in the same folder, and execute:
#   *
#   * ```
#   *     chmod +x ${file}.cs
#   *     ./${file}.cs
#   * ```
#   *
#   * then the mod will be compiled automatically.
#   *
#   * Here we wrote a shebang like file, which is correct
#   * in my computer (Manjaro XFCE), if such script do not work
#   * in your computer, you could just try the instructions below :

export GAME_NAME="${0%\.cs}"                                # might modify if the name mismatch.
export GAME_DIR="$GAME_NAME"                                # might be modified, but "$GAME_NAME" cover most of the cases.

export FILE_NAME="$0"
export ASSEMBLY="Assembly-CSharp"                           # might be modified
export UTILS="utils.cs"                                     # might be modified if you do not put utils.cs in the current dir.
export PLUGIN_ID="Neutron3529.Cheat"                        # should be modified
export NAMESPACE_ID="Neutron3529.Cheat"                     # should be modified
export GAME_BASE_DIR="common/$GAME_DIR"                     # should modify GAME_DIR instead since GAME_DIR == GAME_NAME is almost always true.

export IFS=$'\n' # to disable the annoying space.
export DOTNET="dotnet" # the location of the DOTNET executable file.
[ -z "$DOTNET_CSC_DLL" ] && export DOTNET_CSC_DLL=`\ls /usr/share/dotnet/sdk/*/Roslyn/bincore/csc.dll` # In manjaro, the csc.dll is located in /usr/share/dotnet/sdk/*/Roslyn/bincore/csc.dll

__MODE_VERBOSE=99 # is the line number of "#define VERBOSE", may be modified
__MODE_DEBUG__=$((__MODE_VERBOSE+1))
__MODE_RELEASE=$((__MODE_DEBUG__+1))

case $1 in
    V)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    v)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    VERBOSE) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    verbose) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    D)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    d)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    DEBUG)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    debug)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    *)       _MODE__SELECT_=$__MODE_RELEASE     ;;
esac

( yes "" | head -n $_MODE__SELECT_ | head -n-1  ; tail $FILE_NAME -n+$_MODE__SELECT_ ) | sed s/%%NAMESPACE_ID%%/${NAMESPACE_ID}/g | sed s/%%PLUGIN_ID%%/${PLUGIN_ID}/g | $DOTNET $DOTNET_CSC_DLL -nologo -t:library \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/0Harmony.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.Harmony.dll" \
  `[ -e "${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/netstandard.dll" ] && echo "-r:\"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/netstandard.dll\""` \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/System.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/System.Core.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.AIModule.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.CoreModule.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.UI.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/mscorlib.dll" \
  $(for i in "${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/$ASSEMBLY"*.dll ; do echo -e "-r:\"$i\"\n" ; done) \
  -out:"${GAME_BASE_DIR}/BepInEx/plugins/${FILE_NAME%.*}".dll \
  -optimize `[ "$_MODE__SELECT_" == "$__MODE_DEBUG__" ] && echo -debug` \
  $UTILS - && rm -f "${GAME_BASE_DIR}/BepInEx/config/${PLUGIN_ID}.cfg";

if [ -n "$2" ]; then
    git add ${FILE_NAME}
    case $2 in
        R) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        r) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        RANDOM) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        random) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        U) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        u) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        UPLOAD) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        upload) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        *) git commit -am "$2" ;;
    esac
    git push
fi
exit

#define VERBOSE // the line of __MODE_VERBOSE
#define DEBUG



using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;

using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

namespace %%NAMESPACE_ID%%
{
    [BepInPlugin("%%PLUGIN_ID%%", "%%NAMESPACE_ID%%", "0.1.3")]
    public class Cheat : BaseUnityPlugin {
//         public interface IEntry<T> {
//             public string description {get;set;}
//             public T confval{get;set;}
//             void Init(){
//                 confval=Config.Bind<T>("config",this.GetType(),confval,description).Value;
//                 if(Met(confval)){
//                     harmony.PatchAll(this.GetType());
//                     logger(description+"-patched");
//                 }
//             }
//             bool Met(T confval);
//         }
        public static int roll_min_val=16;
        public static bool equip_extra_citiao=false;
        public static int addpoint=1;
        public static float dan_mul=0;
        public static float delay_mul=0.3f;
        public static sbyte drop_mul=1;
        public static sbyte plant_mul=10;
        public static Dictionary<float,string[]> extra_citiao=new Dictionary<float,string[]>();
        public static int extra_chara_point=45;
        public static HashSet<string> all_extra_citiao=new HashSet<string>();
        public static List<MethodInfo> randomEnhancement=new List<MethodInfo>();
        public static Harmony harmony;
        public static ConfigFile config;

        public abstract class BepInExEntry<T>{
            public ConfigEntry<T> ce;
            public string desc="默认说明";
            public virtual string disable{get{return "默认开关方法说明";}}
            public virtual void Init(ref T confval){
                logger("自动patch遍历到:"+this.GetType().Name); // 调试用
                this.ce=config.Bind("config",this.GetType().Name,confval,this.desc+"（"+this.disable+"）");
                confval=this.ce.Value;
                if(this.Met(confval)){
                    harmony.PatchAll(this.GetType());
                    logger(this.desc+"-patched");
                }
            }
            public virtual bool Met(T confval)=>false;
        }
        public abstract class Bbool : BepInExEntry<bool> {
            public override string disable{get{return "为true时开启";}}
            public bool confval=true;
            public void Init(){
                base.Init(ref this.confval);
            }
            public override bool Met(bool confval)=>confval;
        }
        public abstract class Bfloat : BepInExEntry<float> {
            public override string disable{get{return "不为0时开启";}}
            public override bool Met(float confval)=>confval!=0f;
        }
        public abstract class Bint : BepInExEntry<int> {
            public override string disable{get{return "不为0时开启";}}
            public override bool Met(int confval)=>confval!=0;
        }
        public abstract class Bstring : BepInExEntry<string> {
            public override string disable{get{return "长度大于1时开启";}}
            public override bool Met(string confval)=>confval.Length>1;
        }
        public class Entry1:Bint{
            public static int confval=5;
            public void Init(){
                this.desc="简单测试";
                base.Init(ref confval);
                this.ce.Value+=5;
            }
        }
        public class Entry2:Bint{
            public static int confval=6;
            public void Init(){
                this.desc="简单测试2";
                base.Init(ref confval);
                this.ce.Value+=1;
            }
        }
        void Start() {
            harmony=new Harmony("%%PLUGIN_ID%%");
            config=Config;
            Logger.LogInfo("此Mod使用AGPL-v3许可发布，如果你使用了这里的代码，请按照相同许可发布你修改后的mod。");
#if DEBUG
            logger=Logger.LogInfo;
            logger=delegate(string s){Logger.LogInfo(s);};
            logger("开始注入");
#endif
            Type[] t=new Type[0];
            foreach(var type in (
                from assemblyType in typeof(Cheat).Module.GetTypes()
                where assemblyType.IsSubclassOf(typeof(Bfloat)) || assemblyType.IsSubclassOf(typeof(Bint)) || assemblyType.IsSubclassOf(typeof(Bstring))
                select assemblyType)){
                logger(type.ToString());
                object entry=type.GetConstructor(t).Invoke(t);
                if (entry!=null){
                    type.GetMethod("Init",t).Invoke(entry,t);
                }else{logger("entry："+type+"的type.GetConstructor().Invoke()是null，这多半是mod出了问题，如果你看到这个，请联系mod作者。");}
            }
            if((delay_mul=config.Bind("config", "delay_mul", delay_mul, "增加几个动画速度").Value)<1f){
                if(delay_mul>=0f){
                    harmony.PatchAll(typeof(Neutron3529Faster));
                    logger("增加几个动画速度-patched");
                } else {
                    logger("delay_mul不应当小于0，此时修改被禁用，若希望取消这一行log，请将delay_mul设置为大于1的数值");
                }
            }
#region off
            if((addpoint=config.Bind("config", "addpoint", addpoint, "roll人物时天赋点对属性的影响（小于等于1时关闭此功能）").Value)>1){
                harmony.PatchAll(typeof(CreateChara_AttributesPartAddPoint));
                logger("roll人物时天赋点对属性的影响-patched");
            }
            if((roll_min_val=config.Bind("config", "roll_min_val", roll_min_val, "解除特性之间的相关性，并将特性最小得分设置为此数值（数值大于15时关闭修改，因为这会导致抽不出特性）").Value)<=15){
                harmony.PatchAll(typeof(EntryBuilderGetEntry));
                logger("解除特性之间的相关性，并将特性最小得分设置为此数值-patched-这是roll党的专利，一般情况下“额外人物词条点数”比roll好用");
            }
            if((dan_mul=config.Bind("config", "dan_mul", dan_mul, "炼丹产出乘数（小于等于1时关闭此功能）").Value)>1){
                harmony.PatchAll(typeof(LianDan_LuziFunctioncurrentOutPutNum));
                logger("炼丹产出乘数-patched");
            }
#endregion
#region old
            if((extra_chara_point=config.Bind("config", "total_chara_point", extra_chara_point, "初始人物词条点数（进入选择面板修改时生效）").Value)>0){
                harmony.PatchAll(typeof(CreateChara_RandomEntryPanelinit));
                logger("人物词条点数-patched");
            }
            if(config.Bind("config", "Liandan_shangpin", true, "炼丹只出上品").Value){
                harmony.PatchAll(typeof(LianDan_LuziFunctionGetAllOutpus));
                logger("炼丹只出上品-patched");
            }
            if(config.Bind("config", "zhongzhi_maxspeed", true, "种植，炼丹与炼器一回合完成").Value){
                harmony.PatchAll(typeof(PlantGrowFunctionGetCurrentSpeed));
                harmony.PatchAll(typeof(LianQiFunctioncurrentLianQieRate));
                harmony.PatchAll(typeof(LianDan_LuziFunctioncurrentFireRate));
                logger("种植，炼丹与炼器一回合完成-patched");
            }
            string citiao=config.Bind("config", "citiao", "1&吸血&全属性效果&暴击率&命中率&人物好事件提升|3&大地图行动力提升&成丹值百分比提升&融合度百分比提升&火力值百分比提升|0&符箓距离增加&符箓不阻挡&丹药距离增加&丹药范围增加&稳固&免疫眩晕&免疫变形&免疫禁锢&免疫封禁|45&战斗移动距离提升&平时经验获取提升&战斗角色经验提升&心法经验提升&悟道进度百分比提升&术法精进提升&气运百分比提升&成丹值提升&融合度提升&火力值提升", "额外词条（需开启法宝词条数量和效果变为最大，此处以0开头的词条会将词条效果设置为1，但不会显示数值，关闭此功能时需将词条更改为长度小于等于1的字符串）").Value;
            if((equip_extra_citiao=config.Bind("config", "fabao_citiao_max", true, "法宝词条数量和效果变为最大").Value) || citiao.Length>0){
                harmony.PatchAll(typeof(WholeObjectsCreateAweaponFromFormula));
                if(citiao.Length>0){
                    foreach(string s in citiao.Split('|')){
                        string[] ci=s.Split('&');
                        float f=float.Parse(ci[0]);
                        ci[0]="";
                        if(extra_citiao.ContainsKey(f)){
                            logger("额外词条出现了重复加成，这导致了语句 "+s+" 是无效的，你应当将加成相同的词条放在一起。");
                            continue;
                        }
                        for(int i=0;i<ci.Length;i++){
                            if(ci[i]=="")continue;
                            if(!all_extra_citiao.Add(ci[i])){
                                logger("在 "+s+" 中的词条 "+ci[i]+" 与前文重复，将其无效化");
                                ci[i]="";
                            }
                        }
                        extra_citiao.Add(f,ci);
                    }
                    logger("额外词条-patched");
                }
                if(equip_extra_citiao)logger("法宝词条数量和效果变为最大-patched");
            }

            if(config.Bind("config", "iron_fist", true, "铁拳无敌（空拳可以殴打全体敌方单位，造成流血，眩晕）").Value){
                // 这段程序在 WholeObjects.Awake 之后，因此可以直接修改数据。
                if(AllDictionary.Dic_SkillInfo.ContainsKey("空拳")){
                    AllDictionary.Dic_SkillInfo["空拳"].effectRange="点";
                    AllDictionary.Dic_SkillInfo["空拳"].releaseTarget= TbsFramework.Skill.ReleaseTarget.所有敌方;
                    AllDictionary.Dic_SkillInfo["空拳"].range= 0f;
                    AllDictionary.Dic_SkillInfo["空拳"].cost= 1;
                    for(int i=0;i<1;i++){
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("伤口");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("剧毒");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("伤口不被抵抗");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("剧毒不被抵抗");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("金煞");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("寄生");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("剧毒");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("感电");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("燃烧");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("火蚀");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("溶蚀");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("虚空蚀");
                    }
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("驱散护盾");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("强制眩晕4s");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("脑溢血*");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("封禁5s");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("虚爆");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("风咒·倍");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("雨咒·极");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("强制致残14s");
//                     AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("血蛊摄心·极*");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("血神诅咒");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("血流不止·极");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("极度恐惧");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("人运灭咒·伤");
                    AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("人运灭咒·衰");
                    logger("铁拳无敌-patched");
                }else{
                    logger("铁拳无敌：找不到“空拳”这个技能");
                }
            }
            if((drop_mul=config.Bind("config", "drop_mul", drop_mul, "将可堆叠物品掉落数量变为物品掉落数量最大值乘以此数值（小于等于0时关闭此功能，请不要将数值设置为超过100的数字，那样可能会引发Mod异常）").Value)>0){
                harmony.PatchAll(typeof(WholeObjectsCreateDropItem));
                logger("将可堆叠物品掉落数量变为物品掉落数量最大值乘以此数值-patched");
            }
            if((plant_mul=config.Bind("config", "plant_mul", plant_mul, "将植物产量变为物品掉落数量最大值乘以此数值（小于等于0时关闭此功能，请不要将数值设置为超过100的数字，那样可能会引发Mod异常）").Value)>0){
                harmony.PatchAll(typeof(PlantGrowFunctionGetOutPut));
                logger("将植物产量变为物品掉落数量最大值乘以此数值-patched");
            }
            if(config.Bind("config", "miemen_is_good", true, "灭门善恶增加").Value){
                harmony.PatchAll(typeof(BuildingManagerAttackSect));
                logger("随机数设置为0-灭门善恶增加-added");
            }
            if(config.Bind("config", "miemen_getall", true, "灭门获得全部资源").Value){
                randomEnhancement.Add(typeof(Sect).GetMethod("BeDestroy",(BindingFlags)(-1)));
                logger("随机数设置为0-灭门获得全部资源-added");
            }
            if(config.Bind("config", "robmen_getall", true, "劫掠门派获得全部资源").Value){
                randomEnhancement.Add(typeof(Sect).GetMethod("BeRob",(BindingFlags)(-1)));
                logger("随机数设置为0-劫掠门派获得全部资源-added");
            }
            if(config.Bind("config", "miecity_getall", true, "屠城获得全部资源").Value){
                randomEnhancement.Add(typeof(City).GetMethod("Destroy",(BindingFlags)(-1)));
                logger("随机数设置为0-屠城获得全部资源-added");
            }
            if(config.Bind("config", "robcity_getall", true, "劫掠城市获得全部资源").Value){
                randomEnhancement.Add(typeof(City).GetMethod("BeRob",(BindingFlags)(-1)));
                logger("随机数设置为0-劫掠城市获得全部资源-added");
            }
            if(config.Bind("config", "always_lucky", true, "玩家发生好事件概率为1（不知为何只有面板如此，似乎是善恶系统未实装的缘故）").Value){
                harmony.PatchAll(typeof(ZhuangShiPanelGetBaseGoodEvent));
                logger("玩家发生好事件概率为1-patched");
            }
            if(config.Bind("config", "get_dizi_add_shengwang", true, "强制刷新弟子时获得而非消耗声望").Value){
                harmony.PatchAll(typeof(ZhuiSuiZhePanelForceGetDizi));
                logger("强制刷新弟子时获得而非消耗声望-patched");
            }
            if(config.Bind("config", "qiyun_only", true, "追随者只刷新气运之子").Value){
                harmony.PatchAll(typeof(ZhuiSuiZhePanelZhuiSuiZhe_Create));
                logger("追随者只刷新气运之子-patched");
            }
            if(config.Bind("config", "player_init_with_all_gongfa_and_peifang", true, "初始化门派时加入全部功法与配方").Value){
                harmony.PatchAll(typeof(BuildingManagerCreatePlayerSect));
                logger("初始化门派时加入全部功法与配方-patched");
            }
#endregion
            if(randomEnhancement.Count>0){
                harmony.PatchAll(typeof(RandomEnhancement));
                logger("随机数设置为0-patched");
            }logger("叮~修改器启动，请安心游戏");
            if(config.Bind("config", "dumpSomeData", true, "在log中输出全部丹方材料的五行，武器词条，技能效果，以及其他各种神奇数据").Value){
                foreach(PelletFormulaBook pb in AllDictionary.Dic_PelletFormulaBook.Values){
                    logger(pb.OutCome+":"+pb.Yuansus[0].ToString()+" "+pb.Yuansus[1].ToString()+" "+pb.Yuansus[2].ToString()+" "+pb.Yuansus[3].ToString()+" "+pb.Yuansus[4].ToString()+" ("+pb.ItemRequire+" - "+string.Join(" ",pb.materials)+")");
                }
                foreach(Materials m in AllDictionary.Dic_Material.Values){
                    logger(m.Name+":"+m.Jin+" "+m.Mu+" "+m.Shui+" "+m.Huo+" "+m.Tu);
                }
                foreach(string name in AllDictionary.Dic_BuffInfo.Keys){
                    BuffInfo b=AllDictionary.Dic_BuffInfo[name];
                    logger(name+" 名称 "+b.name+"  BUFF类型 "+b.buffType+"  影响属性 "+b.attriType+"  额外信息 "+b.extraInfo);
                }
                foreach(string name in AllDictionary.Dic_FabaoRandom_Entrys.Keys){
                    FbEntryInfo b=AllDictionary.Dic_FabaoRandom_Entrys[name];
                    logger(name+" 名称 "+b.name+"  BUFF类型 "+b.buff+"  描述 "+b.descrption);
                }
                foreach(string name in AllDictionary.Dic_SkillInfo.Keys){
                    TbsFramework.Skill.SkillInfo s=AllDictionary.Dic_SkillInfo[name];
                    logger(name+" 名称 "+s.skillName+"  2技能体系 "+s.skillSystem+"  子体系 "+s.childSystem+"  3攻击方式 "+s.attackType+"  4元素类型 "+s.MainYuansu+"  5选取范围 "+s.effectRange+"  6施法目标 "+s.releaseTarget+"  7施法范围 "+s.range+"  8消耗行动点数 "+s.cost+"  EffectOnHit \""+string.Join("\",\"",s.EffectOnHit)+"\"  1技能描述 "+s.Description);
                }
                foreach(string name in AllDictionary.Dic_EffectInfo.Keys){
                    EffectInfo s=AllDictionary.Dic_EffectInfo[name];
                    logger(name+" 效果名 "+s.Effectname+"  效果类型 "+s.Effectlist+"  影响属性 "+s.AttributeType+"  元素类型 "+s.YuanSu+"  伤害增幅类型 "+s.DamageType+"  持续时间 "+s.Duration+"  数值参数 "+s.Args+"  IsArgsFromHit0 "+s.IsArgsFromHit0+"  MaxStucks "+s.MaxStucks);
                }
                foreach(string name in AllDictionary.Dic_XinFa.Keys){
                    XinFa s=AllDictionary.Dic_XinFa[name];
                    logger(name+" 名称 "+s.Name+"  稀有度 "+s.rare+"  修炼类型 "+s.type+"  子体系 \""+string.Join("\",\"",s.childTypes)+"\"");
                }
                foreach(string name in AllDictionary.Dic_ShuFa.Keys){
                    ShuFa s=AllDictionary.Dic_ShuFa[name];
                    logger(name+" 名称 "+s.Name+"  稀有度 "+s.rare+"  等级 "+s.shufaRare+"  修炼体系 "+s.xiuliantype+"  子体系 \""+string.Join("\",\"",s.childXiuliantypes)+"\"");
                }
            }
        }
#region oldimpl
        class Neutron3529Faster {
            static IEnumerable<MethodBase> TargetMethods(){
                foreach(MethodInfo i in new MethodInfo[]{
                    typeof(SearchPanel).GetMethod("TextChange",(BindingFlags)(-1)),
//                     typeof(SayDialog).GetMethod("IconFlicker",(BindingFlags)(-1)),
                    typeof(CharaWalker).GetMethod("TypeString",(BindingFlags)(-1)),
                    typeof(DisplayPanel).GetMethod("DisplayOnPanel",(BindingFlags)(-1))
                }){
                    if(i==null){logger("FATAL:NULL i");}else{
                        logger("修改类别"+i.ToString()+"的MoveNext方法");
                        if(AccessTools.EnumeratorMoveNext(i)!=null){yield return AccessTools.EnumeratorMoveNext(i);}else{logger("error:i="+i.ToString()+", have no move next");}
                    }
                }
            }
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Newobj,typeof(UnityEngine.WaitForSeconds).GetConstructor(new Type[]{typeof(float)}))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldc_R4,delay_mul),
                            new CodeInstruction(OpCodes.Mul)
                        )
                        .Advance(1),logger
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [HarmonyPatch(typeof(EntryBuilder), "GetEntry")]
        class EntryBuilderGetEntry {
            static void Prefix(int[] PoolRange, bool isPlayer){
                if (isPlayer){
                    PoolRange[0]=roll_min_val;
                    PoolRange[1]=1000;
                }
            }
        }
        [HarmonyPatch(typeof(CreateChara_AttributesPart), "AddPoint",new Type[]{typeof(object),typeof(string)})]
        class CreateChara_AttributesPartAddPoint {
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Dup),
                        new CodeMatch(OpCodes.Ldind_I4),
                        new CodeMatch(OpCodes.Ldc_I4_1),
                        new CodeMatch(OpCodes.Add)
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .Advance(2) // Move cursor to after ldfld
                        .SetAndAdvance(
                            OpCodes.Ldc_I4,addpoint
                        )
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [HarmonyPatch(typeof(LianDan_LuziFunction), "GetAllOutpus")]
        class LianDan_LuziFunctionGetAllOutpus {
            static List<PelletNameAndWeight> Postfix(List<PelletNameAndWeight> result){
                float counter=0f;
                foreach(PelletNameAndWeight x in result){
                    if(x.PelletName.Contains("·下品") || x.PelletName.Contains("·中品") ){
                        counter+=x.Weight;
                        x.Weight=0f;
                    } else if (x.PelletName.Contains("·上品")){
                        x.Weight+=counter;
                        counter=0f;
                    }
                }
                return result;
            }
        }
        [HarmonyPatch(typeof(LianDan_LuziFunction), "currentOutPutNum",MethodType.Getter)]
        class LianDan_LuziFunctioncurrentOutPutNum {
            static float Postfix(float result){
                return result*dan_mul;
            }
        }
        [HarmonyPatch(typeof(PlantGrowFunction), "GetCurrentSpeed")]
        class PlantGrowFunctionGetCurrentSpeed {
            static bool Prefix(ref float __result,float ___MaxProcess){
                __result=___MaxProcess;
                return false;
            }
        }
        [HarmonyPatch(typeof(LianQiFunction), "currentLianQieRate",MethodType.Getter)]
        class LianQiFunctioncurrentLianQieRate {
            static bool Prefix(ref float __result,float ___MaxProcess){
                __result=___MaxProcess;
                return false;
            }
        }
        [HarmonyPatch(typeof(LianDan_LuziFunction), "currentFireRate",MethodType.Getter)]
        class LianDan_LuziFunctioncurrentFireRate {
            static bool Prefix(ref float __result,float ___MaxProcess){
                __result=___MaxProcess;
                return false;
            }
        }
        [HarmonyPatch(typeof(WholeObjects), "CreateAweaponFromFormula")]
        class WholeObjectsCreateAweaponFromFormula {
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldarg_1),
                        new CodeMatch(OpCodes.Ldfld,typeof(WeaponFormula).GetField("Outcome",(BindingFlags)(-1))),
                        new CodeMatch(i=>i.opcode==OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "initialize")
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Dup)
                        )
                        .Advance(3)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldarg_2),
                            new CodeInstruction(OpCodes.Call,typeof(WholeObjectsCreateAweaponFromFormula).GetMethod("abconvert"))
                        )
                    ).InstructionEnumeration();
                return instructions;
            }
            public static void abconvert(AbstractWeapon abw,string s){
                if (s=="S_0" && abw.randomEntry.Count==0){
                    Weapon weapon = AllDictionary.Dic_Weapon[abw.Name];
                    if(equip_extra_citiao){
                        foreach(var entry in AllDictionary.Dic_FabaoRandom_Entrys.Keys) {
                            //if(all_extra_citiao.Contains(entry))continue;// 这个增加值与主动增加不同，故可以保留
                            // abstractWeapon.randomEntry.Add(EntryBuilder.GetRandomEntry(text2, weapon, null));
                            string text2="";
                            string text="+";
                            float num2;
                            FbEntryInfo fbEntryInfo = AllDictionary.Dic_FabaoRandom_Entrys[entry];
                            float computerValue2 = (float)(typeof(EntryBuilder).GetMethod("GetComputerValue",(BindingFlags)(-1)).Invoke(null,new object[]{fbEntryInfo.max, weapon.Level}));
                            if(computerValue2<=0)computerValue2=(float)(typeof(EntryBuilder).GetMethod("GetComputerValue",(BindingFlags)(-1)).Invoke(null,new object[]{fbEntryInfo.min, weapon.Level}));
                            if(fbEntryInfo.isInteger) {
                                int num=((int)computerValue2) * (1 + weapon.Level * (int)(1 + weapon.Rare) / 26);
                                num2=(float)num;
                                text2=num.ToString();
                            } else {
                                num2 = (float)Convert.ToInt32(computerValue2 * 100f)/100f;

                                if (fbEntryInfo.isPercentShow)
                                {
                                    text2 = num2.ToString("P0");
                                }
                                else
                                {
                                    text2 = num2.ToString("0.0");
                                }
                            }

                            if (num2 < 0f)
                            {
                                text = "";
                            }
                            text2 = fbEntryInfo.descrption + text + text2;
                            if(num2!=0f){
                                abw.randomEntry.Add(new RandomEntry{
                                    description = text2,
                                    name = fbEntryInfo.name,
                                    buffName = fbEntryInfo.buff,
                                    value = num2,
                                    id = Guid.NewGuid().ToString()
                                });
                            }
                        }
                    }
                    foreach(var kv in extra_citiao){
//                         logger("进入extra_citiao,k="+kv.Key+"v="+string.Join(" ",kv.Value));
                        foreach(var entry in kv.Value) {
                            if(AllDictionary.Dic_BuffInfo.ContainsKey(entry)){
                                BuffInfo buffInfo = AllDictionary.Dic_BuffInfo[entry];
                                var num2=kv.Key;
                                string text="";
                                string text2;
                                if (buffInfo.isPercentage || entry=="吸血" || entry=="全属性效果" || entry=="暴击率" || entry=="命中率") {
                                    text2 = num2.ToString("P0");
                                } else {
                                    text2 = num2.ToString("0.0");
                                }
                                if(num2<0f){
                                    text=text2;
                                }else if (num2>0f){
                                    text="+"+text2;
                                }else{
                                    num2=1f;
                                }
                                abw.randomEntry.Add(new RandomEntry{
                                    description = buffInfo.name + text,
                                    name = buffInfo.name,
                                    buffName = buffInfo.name,
                                    value = num2,
                                    id = Guid.NewGuid().ToString()
                                });
                            } else if (entry!=""){
                                logger("在Dic_FabaoRandom_Entrys信息中找不到"+entry);
                            }
                        }
                    }
                }
            }
        }
        [HarmonyPatch(typeof(WholeObjects), "CreateDropItem")]
        class WholeObjectsCreateDropItem {
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(DropItem).GetField("minCount"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .SetAndAdvance(
                            OpCodes.Ldfld,typeof(DropItem).GetField("maxCount")
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(DropItem).GetField("maxCount"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldc_I4_S,(int)drop_mul),
                            new CodeInstruction(OpCodes.Mul)
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [HarmonyPatch(typeof(PlantGrowFunction), "GetOutPut")]
        class PlantGrowFunctionGetOutPut {
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(PlantClass).GetField("output_min"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .SetAndAdvance(
                            OpCodes.Ldfld,typeof(PlantClass).GetField("output_max")
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(PlantClass).GetField("output_max"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldc_I4_S,(int)plant_mul),
                            new CodeInstruction(OpCodes.Mul)
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [HarmonyPatch(typeof(CreateChara_RandomEntryPanel), "init")]
        class CreateChara_RandomEntryPanelinit {
            static void Postfix(ref int ___CurrentPoint,int ___MaxPoint){
                ___CurrentPoint+=extra_chara_point-___MaxPoint;
            }
        }
        class RandomEnhancement {
            static IEnumerable<MethodBase> TargetMethods(){
                foreach(MethodInfo m in randomEnhancement){
                    yield return m;
                }
            }
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Call,typeof(UnityEngine.Random).GetMethod("Range",new Type[]{typeof(int),typeof(int)}/*, and maybe some BindingFlags here*/))
                    ).Repeat( matcher =>
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Pop),
                            new CodeInstruction(OpCodes.Ldc_I4_0)
                        )
                        .Advance(1),logger
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [HarmonyPatch(typeof(BuildingManager), "AttackSect")]
        class BuildingManagerAttackSect {
            static void Postfix(){
                Sect sect = WholeObjects.Instance.Dic_Sect["S_0"];
                sect.shengWang += 1000;
                sect.shanE += 100;
                WholeObjects.Instance.GetPlayer().shane += 100;
            }
        }
        [HarmonyPatch(typeof(ZhuangShiPanel), "GetBaseGoodEvent")]
        class ZhuangShiPanelGetBaseGoodEvent {
            static bool Prefix(ref float __result){
                __result=10f;
                return false;
            }
        }
        [HarmonyPatch(typeof(ZhuiSuiZhePanel), "ForceGetDizi")]
        class ZhuiSuiZhePanelForceGetDizi {
            static void Prefix(){
                WholeObjects.Instance.GetPlayerSect().shengWang+=200;
            }
        }
        [HarmonyPatch(typeof(ZhuiSuiZhePanel), "ZhuiSuiZhe_Create")]
        class ZhuiSuiZhePanelZhuiSuiZhe_Create {
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Call,typeof(GeneralUtils).GetMethod("RandomBornRare",new Type[]{typeof(int),typeof(int)}))
                    ).Repeat( matcher =>
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Pop),
                            new CodeInstruction(OpCodes.Ldc_I4_S,(int)Inborn.气运)
                        )
                        .Advance(1),logger
                    ).InstructionEnumeration();
                return instructions;
            }

        }
#endregion
#if DEBUG
        public static Action<string> logger;
#else
        public static void logger(string s){}
#endif
    }
}

